package com.gitee.ixtf.vertx.internal.converter

import com.gitee.ixtf.vertx.ParameterConverter
import graphql.schema.DataFetchingEnvironment
import java.lang.reflect.Parameter
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import org.dataloader.DataLoader

private var DATA_LOADER_NAME_MAP: Map<String, String> = mapOf()

fun registerDataLoaderName(clazz: Class<*>) {
  DATA_LOADER_NAME_MAP += dataLoaderName(clazz.genericInterfaces[0]) to clazz.name
}

private fun dataLoaderName(type: Type): String {
  val parameterizedType = type as ParameterizedType
  val k = parameterizedType.actualTypeArguments[0]
  val v = parameterizedType.actualTypeArguments[1]
  return k.typeName + v.typeName
}

class DataLoaderParamParameterConverter(
    private val parameter: Parameter,
) : ParameterConverter<DataLoader<*, *>> {
  private val dataLoaderName by lazy {
    DATA_LOADER_NAME_MAP[dataLoaderName(parameter.parameterizedType)]
  }

  override suspend fun convert(env: DataFetchingEnvironment) =
      env.getDataLoader<Any, Any>(dataLoaderName)!!
}
